﻿using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Xml;
using AttachedCommands.ACB;
using Microsoft.Win32;
using Snippet2Vsi.Classes;

namespace Snippet2Vsi.ViewModels
{
    public class SnippetMergerViewModel:ViewModelBase
    {
        #region Members

        private RelayCommand _browseComamnd;
        private string _snippetLocation;
        private RelayCommand _addCommand;
        private RelayCommand _deleteCommand;
        private RelayCommand _clearCommand;
        private RelayCommand _mergeCommand;

        #endregion

        #region Commands

        public RelayCommand BrowseComamnd
        {
            get { return _browseComamnd ?? (_browseComamnd = new RelayCommand(BrowseComamndHandler)); }
            set { _browseComamnd = value; }
        }

       

        public RelayCommand AddCommand
        {
            get { return _addCommand ?? (_addCommand = new RelayCommand(AddCommandHandler)); }
            set { _addCommand = value; }
        }

        

        public RelayCommand DeleteCommand
        {
            get { return _deleteCommand ?? (_deleteCommand = new RelayCommand(DeleteCommandHandler)); }
            set { _deleteCommand = value; }
        }


        

        public RelayCommand ClearCommand
        {
            get { return _clearCommand ?? (_clearCommand = new RelayCommand(ClearCommandHandler)); }
            set { _clearCommand = value; }
        }

       

        public RelayCommand MergeCommand
        {
            get { return _mergeCommand ?? (_mergeCommand = new RelayCommand(MergeCommandHandler)); }
            set { _mergeCommand = value; }
        }

       


        #endregion

        #region Handlers

        private void MergeCommandHandler(object obj)
        {
           TryCatch.BeginTryCatch(Merge);
        }

        private void ClearCommandHandler(object obj)
        {
            TryCatch.BeginTryCatch(Clear); 
        }

        private void BrowseComamndHandler(object obj)
        {
            TryCatch.BeginTryCatch(Browse);
        }

        private void AddCommandHandler(object obj)
        {
            TryCatch.BeginTryCatch(Add);
        }

        private void DeleteCommandHandler(object obj)
        {

            TryCatch.BeginTryCatch(() => SnippetFiles.Where(sn => sn.Checked).ToList().ForEach(
                sn => SnippetFiles.Remove(sn)));
           
        }
        #endregion

        #region Methods

        private void Browse()
        {
            var saveFileDialog = new SaveFileDialog
            {
                Filter = "Code Snippets (.snippet)|*.snippet"
            };
            saveFileDialog.ShowDialog();
            if (!string.IsNullOrEmpty(saveFileDialog.FileName))
            {
                SnippetLocation = saveFileDialog.FileName;
            }
        }

        private void Clear()
        {
            var result = MessageBox.Show("Are you sure you want to delete all files?", "", MessageBoxButton.YesNo,
                                         MessageBoxImage.Question);
            if (result == MessageBoxResult.Yes)
            {
                SnippetFiles.Clear();
            }
        }

        private void Add()
        {
            var openFileDailog = new OpenFileDialog
            {
                CheckFileExists = true,
                Multiselect = true,
                Filter = "Code Snippets (.snippet)|*.snippet"
            };
            openFileDailog.ShowDialog();
            if (string.IsNullOrEmpty(openFileDailog.FileName)) return;

            foreach (var fileName in openFileDailog.FileNames)
            {
                var reader = XmlReader.Create(fileName);
                reader.Read();
                if (reader.IsStartElement())
                {
                    var snippetFile = new SnippetFile { File = fileName, Checked = false };

                    if (reader.Name == "CodeSnippets")
                    {
                        if (SnippetFiles.Count(sn => sn.File == snippetFile.File) > 0)
                        {
                            MessageBox.Show("This file " + snippetFile.File + " is already added", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                        else
                        {
                            SnippetFiles.Add(snippetFile);
                        }

                    }
                    else
                    {
                        MessageBox.Show("First element in snippet file should be CodeSnippets.Please rectify it and try again later", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                }
            }
        }

        private void Merge()
        {
            var error = ValidateForm();
            if (!string.IsNullOrEmpty(error))
            {
                MessageBox.Show(error, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            var wSettings = new XmlWriterSettings { Indent = true };
            using (var writter = XmlWriter.Create(SnippetLocation, wSettings))
            {
                // Root.

                writter.WriteStartDocument();
                writter.WriteStartElement("CodeSnippets",
                                          "http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet");

                //Add Elements
                foreach (var sn in SnippetFiles)
                {
                    XmlReader reader = XmlReader.Create(sn.File);
                    reader.Read();
                    if (reader.IsStartElement())
                        reader.Read();

                    while (reader.Read())
                    {
                        if (reader.NodeType == XmlNodeType.Element && reader.Name != "CodeSnippets")
                        {
                            writter.WriteNode(reader, true);
                        }
                    }
                }
                // Result is a string.
                writter.WriteEndDocument();
            }

            MessageBox.Show("All snippets merged successfully!", "Done", MessageBoxButton.OK,
                            MessageBoxImage.Information);
            return;
        }

        private string ValidateForm()
        {
            var error = "";

            if (string.IsNullOrEmpty(SnippetLocation))
                error = "Snippet Location cannot be blank";
            if (SnippetLocation != null) 
               if( SnippetLocation.LastIndexOf(".snippet")!=SnippetLocation.Length-8)
                   error = "Snippet Location extension shuld be .snippet";
            return error;
        }

        #endregion

        #region Properties



        public string SnippetLocation
        {
            get
            {
               
                return _snippetLocation;
            }
            set
            {
                _snippetLocation = value;
                NotifyPropertyChanged(this,o=>o.SnippetLocation);
            }
        }


        private ObservableCollection<SnippetFile> _snippetFiles;

        public ObservableCollection<SnippetFile> SnippetFiles
        {
            get { return _snippetFiles ?? (_snippetFiles = new ObservableCollection<SnippetFile>()); }
            set
            {
                _snippetFiles = value;
                NotifyPropertyChanged(this, o => o.SnippetFiles);
            }
        }
 
        #endregion
    }

    #region Classes

    public class SnippetFile
    {
        public bool Checked { get; set; }
        public string File { get; set; }
    }
    #endregion
}
